查看原文
其他

云计算的前世今生2:容器的诞生

2017-02-04 刘超 网易云


小编点评:《云计算的前世今生1:从物理设备到云计算》中介绍了云计算发展脉络的前三阶段:第一阶段“合,即物理设备”;第二阶段“分,即虚拟化”;第三阶段“合,即云计算”。本篇继续介绍云计算发展第四阶段:“分,即容器”。




云计算发展第四阶段:分,即容器





 

容器前传:PaaS

前面一直在讲IaaS层的故事,基本上在谈计算、网络、存储的事情。现在应该说说应用层,即PaaS层的事情了。


1、PaaS的定义与作用

IaaS的定义比较清楚,PaaS的定义就没那么清楚了,有的把数据库,负载均衡,缓存作为PaaS服务,有的把大数据Hadoop, Spark平台作为PaaS服务,有的讲应用的安装与管理,例如Puppet, Chef, Ansible作为PaaS服务。


其实PaaS主要用于管理应用层的,我总结两部分:一部分是你自己的应用应当自动部署,比如Puppet, Chef, Ansible, Cloud Foundry等,可以通过脚本帮你部署,一部分是你觉得复杂的通用应用不用部署,比如数据库,缓存,大数据平台,可以在云平台上一点即得。


要么就是自动部署,要么不用部署,总的来说就是应用层您也少操心,就是PaaS的作用。当然最好是都不用部署,一键可得,所以公有云平台将通用的服务都做成了PaaS平台。另一些应用,是您自己开发的,除了你自己,其他人都不知道,所以您可以用工具变成自动部署。


2、PaaS的优点

PaaS最大的优点,就是可以实现应用层的弹性伸缩。比如双十一来了,10个节点要变成100个节点,如果使用物理设备,再买90台机器固然来不及,仅仅只有IaaS实现资源的弹性是不够的,再创建90台虚拟机,也是空的啊,还是需要运维人员一台一台的部署。所以有了PaaS就好了,一台虚拟机启动后,马上运行自动部署脚本,进行应用的安装,90台机器自动安装好应用,这才是真正的弹性伸缩。


3、PaaS部署的问题

当然这种部署方式也有一个问题,无论Puppet,Chef,Ansible把安装脚本抽象的再好,说到底也是基于脚本的,然而应用所在的环境千差万别,文件路径的差别,文件权限的差别,依赖包的差别,应用环境的差别,Tomcat,PHP, Apache等软件版本的差别,JDK,Python等版本的差别,是否安装了一些系统软件,是否占用了哪些端口,都可能造成脚本执行的不成功。所以看起来是一旦脚本写好,就能够快速复制了,但是一旦环境稍有改变,就需要把脚本进行新一轮的修改,测试,联调。例如在数据中心写好的脚本,移到AWS上就不一定直接能用,在AWS上联调好了,迁移到Google Cloud上去也可能再会出问题。


 

容器的诞生

云计算解决了基础资源层的弹性伸缩,却没有解决PaaS层应用随基础资源层弹性伸缩而带来的批量、快速部署问题。于是容器应运而生。


容器是Container,Container另一个意思是集装箱,其实容器的思想就是要变成软件交付的集装箱。集装箱的特点,一是打包,二是标准。


没有集装箱的时代,假设将货物从A运到B,中间要经过三个码头,换三次船。每次都要将货物卸下船来,摆的七零八落,然后搬上船重新整齐摆好。因此在没有集装箱的时候,每次换船,船员们都要在岸上待几天才能走。


有了集装箱以后,所有的货物都打包在一起了,并且集装箱的尺寸全部一致,所以每次换船的时候,一个箱子整体搬过去就行了,小时级别就能完成,船员再也不能上岸长时间耽搁了。


这是集装箱“打包”、“标准”两大特点在生活中的应用。下面用一个简单的案例来看看容器在开发部署中的实际应用。


假设有一个简单的Java网站需要上线,代码的运行环境如下:

看,一个简单的Java网站,就有这么多零零散散的东西!这就像很多零碎的货物,如果不打包,就需要在开发、测试、生产的每个环境上重新查看以保证环境的一致,有时甚至要将这些环境重新搭建一遍,就像每次将货物卸载、重装一样麻烦。中间稍有差池,比如开发环境用了JDK 1.8,而线上是JDK 1.7;比如开发环境用了root用户,线上需要使用hadoop用户,都可能导致程序的运行失败。

那么容器如何对应用打包呢?还是要学习集装箱,首先要有个封闭的环境,将货物封装起来,让货物之间互不干扰,互相隔离,这样装货卸货才方便。好在Ubuntu中的LXC技术早就能做到这一点。


封闭的环境主要使用了两种技术,一种是看起来是隔离的技术,称为namespace,也即每个namespace中的应用看到的是不同的IP地址、用户空间、程号等。另一种是用起来是隔离的技术,称为cgroup,也即明明整台机器有很多的CPU、内存,而一个应用只能用其中的一部分。


有了这两项技术,集装箱的铁盒子我们是焊好了,接下来是决定往里面放什么。

最简单粗暴的方法,就是将上面列表中所有的都放到集装箱里面。但是这样太大了!因为即使你安装一个干干静静的Ubuntu操作系统,什么都不装,就很大了。把操作系统装进容器相当于把船也放到了集装箱里面!传统的虚拟机镜像就是这样的,动辄几十G。答案当然是NO!所以第一项操作系统不能装进容器。


撇下第一项操作系统,剩下的所有的加起来,也就几百M,就轻便多了。因此一台服务器上的容器是共享操作系统内核的,容器在不同机器之间的迁移不带内核,这也是很多人声称容器是轻量级的虚拟机的原因。轻不白轻,自然隔离性就差了,一个容器让操作系统崩溃了,其他容器也就跟着崩溃了,这相当于一个集装箱把船压漏水了,所有的集装箱一起沉。


另一个需要撇下的就是随着应用的运行而产生并保存在本地的数据。这些数据多以文件的形式存在,例如数据库文件、文本文件。这些文件会随着应用的运行,越来越大,如果这些数据也放在容器里面,会让容器变得很大,影响容器在不同环境的迁移。而且这些数据在开发、测试、线上环境之间的迁移是没有意义的,生产环境不可能用测试环境的文件,所以往往这些数据也是保存在容器外面的存储设备上。也是为什么人们称容器是无状态的。


至此集装箱焊好了,货物也装进去了,接下来就是如何将这个集装箱标准化,从而在哪艘船上都能运输。这里的标准一个是镜像,一个是容器的运行环境。


所谓的镜像,就是将你焊好集装箱的那个时刻,将集装箱的状态保存下来,就像孙悟空说定,集装箱里面就定在了那一刻,然后将这一刻的状态保存成一系列文件。这些文件的格式是标准的,谁看到这些文件,都能还原当时定住的那个时刻。将镜像还原成运行时的过程(就是读取镜像文件,还原那个时刻的过程)就是容器的运行的过程。除了大名鼎鼎的Docker,还有其他的容器,例如AppC,Mesos Container,都能运行容器镜像,所以说容器不等于Docker


总而言之,容器是轻量级的、隔离差的、适用于无状态的,可以基于镜像标准实现跨主机、跨环境的随意迁移。

有了容器,PaaS层对用户自身应用的自动部署变得快速而优雅。容器快,快在两方面,第一是虚拟机启动的时候要先启动操作系统,容器不用启动操作系统,因为是共享内核的。第二是虚拟机启动后使用脚本安装应用,容器不用安装应用,因为已经打包在镜像里面了。所以最终虚拟机的启动是分钟级别,而容器的启动是秒级。容器咋这么神奇。其实一点都不神奇,第一是偷懒少干活了,第二是提前把活干好了。


因为容器的启动快,人们往往不会创建一个个小的虚拟机来部署应用,因为这样太费时间了,而是创建一个大的虚拟机,然后在大的虚拟机里面再划分容器,而不同的用户不共享大的虚拟机,可以实现操作系统内核的隔离。这又是一次合久必分的过程。由IaaS层的虚拟机池,划分为更细粒度的容器池。


本文作者网易云首席解决方案架构师 刘超 )


点击阅读

连载:《云计算的前世今生1:从物理设备到云计算》

连载:《云计算的前世今生3:容器管理平台初体验》,待续

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存